package org.zhuzx.util;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 并发工具类
 * @author	zhuzx	2017年5月22日
 */
public class ConcurrentUtil {
	
	/** 统一管理任务调度，避免系统中产生众多调度线程。 */
	private static final ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
	
	/**
	 * 单次调度，时间单位为毫秒。
	 */
	public static void schedule(Runnable task, long initialDelay) {
		ses.schedule(task, initialDelay, TimeUnit.MILLISECONDS);
	}
	
	/**
	 * 固定速率调度，时间单位为毫秒。
	 */
	public static void scheduleAtFixedRate(Runnable task, long initialDelay, long period) {
		ses.scheduleAtFixedRate(task, initialDelay, period, TimeUnit.MILLISECONDS);
	}
	
	/**
	 * 固定间隔调度，时间单位为毫秒。
	 */
	public static void scheduleWithFixedDelay(Runnable task, long initialDelay, long delay) {
		ses.scheduleWithFixedDelay(task, initialDelay, delay, TimeUnit.MILLISECONDS);
	}
	
	/**
	 * 关闭调度器并停止所有调度任务
	 */
	public static void shutdownNow() {
		ses.shutdownNow();
	}
	
	/**
	 * 以线程池方式执行Callable任务并返回结果集，本方法是同步的，需要等待所有任务执行完毕。
	 * @param cla 实现Callable接口的任务类
	 * @param threadNum 线程数量
	 * @return 所有任务完成后再统一返回结果集，由任务类定义返回结果的类型（泛型参数R）。
	 */
	public static <C extends Callable<R>, R> List<R> poolInvokeAll(Class<C> cla, int threadNum) throws Exception {
		List<C> tasks = new ArrayList<C>(threadNum);
		for (int i=1; i<=threadNum; i++) {
			tasks.add(cla.newInstance());
		}
		ExecutorService pool = Executors.newFixedThreadPool(threadNum);
		List<Future<R>> futures = pool.invokeAll(tasks);
		pool.shutdown();
		List<R> result = new ArrayList<R>();
		for (Future<R> fu : futures) {
			result.add(fu.get());
		}
		return result;
	}
	
}